package pl.iachoo.ctl.tabory.dao.hibernate.services.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.hibernate.criterion.Restrictions;

import pl.iachoo.ctl.tabory.dao.api.services.IUserService;
import pl.iachoo.ctl.tabory.dao.data.vo.UserVO;
import pl.iachoo.ctl.tabory.dao.hibernate.services.BaseDaoService;

public class UserDaoServiceImpl extends BaseDaoService<UserVO> implements
		IUserService {

	private final Logger logger = Logger.getLogger(UserDaoServiceImpl.class);

	public UserDaoServiceImpl(SessionFactory sessionFactory) {
		super(sessionFactory);
	}

	@Override
	public void deleteUser(UserVO user) throws Exception {
		logger.debug("Deleting: " + user);
		Transaction transaction = null;
		Session session = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			UserVO tmpUser = (UserVO) session.get(UserVO.class, user.getId());
			session.delete(tmpUser);
			transaction.commit();
			logger.debug("Delete OK.");
		} catch (Exception e) {
			transaction.rollback();
			logger.error(e.getMessage(), e);
			throw e;
		} finally {
			session.close();
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<UserVO> getAllUsers() throws Exception {
		logger.debug("Getting all Users");
		Transaction transaction = null;
		Session session = null;
		List<UserVO> listUser = new ArrayList<UserVO>();
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			Criteria criteria = session.createCriteria(UserVO.class);
			listUser = criteria.list();
			transaction.commit();
			logger.debug(listUser);
		} catch (Exception e) {
			transaction.rollback();
			logger.error(e.getMessage(), e);
			throw e;
		} finally {
			session.close();
		}
		return listUser;
	}

	@Override
	public UserVO getUser(String userLogon) throws Exception {
		logger.debug("Getting User for userLogon: " + userLogon);
		Transaction transaction = null;
		Session session = null;
		UserVO user = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			Criteria criteria = session.createCriteria(UserVO.class);
			criteria.add(Restrictions.eq("userLogon", userLogon));
			user = (UserVO) criteria.uniqueResult();
			transaction.commit();
			logger.debug(user);
		} catch (Exception e) {
			transaction.rollback();
			logger.error(e.getMessage(), e);
			throw e;
		} finally {
			session.close();
		}
		return user;
	}

	@Override
	public UserVO getUser(Long userId) throws Exception {
		logger.debug("Getting User for Id: " + userId);
		Transaction transaction = null;
		Session session = null;
		UserVO user = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			Criteria criteria = session.createCriteria(UserVO.class);
			criteria.add(Restrictions.eq("id", userId));
			user = (UserVO) criteria.uniqueResult();
			transaction.commit();
			logger.debug(user);
		} catch (Exception e) {
			transaction.rollback();
			logger.error(e.getMessage(), e);
			throw e;
		} finally {
			session.close();
		}
		return user;
	}

	@Override
	public UserVO saveUpdateUser(UserVO user) throws Exception {
		logger.debug("Save/Update user: " + user);
		if (user.getId() != null) {
			updateUser(user);
		} else {
			saveUser(user);
		}
		return user;
	}

	private void saveUser(UserVO user) throws Exception {
		logger.debug("Saving user: " + user);
		Transaction transaction = null;
		Session session = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			session.save(user);
			transaction.commit();
		} catch (Exception e) {
			transaction.rollback();
			logger.error(e.getMessage(), e);
			throw e;
		} finally {
			session.close();
		}
	}

	private void updateUser(UserVO user) throws Exception {
		logger.debug("Updating user: " + user);
		Transaction transaction = null;
		Session session = null;
		try {
			session = sessionFactory.openSession();
			transaction = session.beginTransaction();
			transaction.begin();
			session.update(user);
			transaction.commit();
		} catch (Exception e) {
			transaction.rollback();
			logger.error(e.getMessage(), e);
			throw e;
		} finally {
			session.close();
		}
	}

}
